package com.qingchi.server.social;

import com.qingchi.base.constant.AuthType;
import com.qingchi.base.model.account.DevAccountDO;
import com.qingchi.base.model.openData.ThreeUserDO;
import com.qingchi.base.model.user.TokenDO;
import com.qingchi.base.utils.UserUtils;
import com.socialuni.social.constant.ErrorCode;
import com.socialuni.social.exception.SocialUserBannedException;
import com.socialuni.social.model.DO.user.SocialUserDO;
import com.qingchi.base.modelVO.user.UserDetailBO;
import com.qingchi.base.repository.openData.DevAccountRepository;
import com.qingchi.base.repository.openData.ThreeUserRepository;
import com.qingchi.base.repository.user.TokenRepository;
import com.qingchi.base.utils.DevAccountUtils;
import com.socialuni.social.utils.TokenUtils;
import com.qingchi.server.openData.ThreeAuthUserInfoQueryVO;
import com.socialuni.social.model.RO.user.OAuthUserInfoRO;
import com.qingchi.server.openData.ThreeAuthUserPhoneNumResultVO;
import com.socialuni.social.api.OAuthApi;
import com.socialuni.social.model.RO.user.OAuthUserRO;
import com.socialuni.social.model.common.ResultRO;
import com.socialuni.social.model.QO.user.OAuthUserQO;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Optional;

//授权用户信息
@RestController
@RequestMapping("oauth")
public class OauthController implements OAuthApi {

    @Resource
    private DevAccountRepository devAccountRepository;

    @Resource
    private TokenRepository tokenRepository;
    @Resource
    private ThreeUserRepository threeUserRepository;


    @Override
    //app端，小程序端，微信和qq登陆的接口，传入第三方返回的基础信息，昵称等，没有手机号，Provider = 'weixin' | 'qq'
    @PostMapping("getUserInfo")
    public ResultRO<OAuthUserInfoRO> getUserInfo(@RequestBody @Valid @NotNull OAuthUserQO authVO) {
        String token = authVO.getToken();

        SocialUserDO user = null;
        try {
            user = UserUtils.getUserByDBNoViolation(token);
        } catch (SocialUserBannedException e) {
            return new ResultRO<>(ErrorCode.BANNED_ERROR);
        }
//        UserDO user = UserUtils.getMineUser();
        assert user != null;

        //等于校验了，devId，
        //目前只有清池可以授权
       /* if (!devId.equals(1)) {
            return new ResultVO<>("不允许授权");
        }*/


        //还能知道密钥是否被盗用
        //校验密钥是否正确
        /*Optional<DevAccountDO> devAccountDOOptional = ;

        if (!devAccountDOOptional.isPresent()) {
            return new ResultVO<>("不存在的开发者商户");
        }*/

        DevAccountDO threeDevDO = DevAccountUtils.getDevAccount();

        assert threeDevDO != null;
        //只是记录一个授权记录
        ThreeUserDO threeUserDO = new ThreeUserDO(1, authVO.getAppUserId(), user.getUserId(), AuthType.user);

        threeUserDO = threeUserRepository.save(threeUserDO);
        //token有效期三个月
        //生成userToken
        String userToken = TokenUtils.generateTokenById(user.getId(), threeDevDO.getDevNum());
        TokenDO tokenDO = tokenRepository.save(new TokenDO(userToken, user.getId(), threeDevDO.getId()));
        OAuthUserRO userDetailVO = new UserDetailBO(user, true, threeDevDO.getId()).toSocialVO();
        //生成返回对象
        OAuthUserInfoRO oAuthUserInfoRO = new OAuthUserInfoRO();
        oAuthUserInfoRO.setToken(tokenDO.getTokenCode());
        oAuthUserInfoRO.setUser(userDetailVO);
        //应该使用三方devId，设置用户信息
//        oAuthUserInfoResultVO.setUser();
        return new ResultRO<>(oAuthUserInfoRO);
        //然后三方应用就能拿着这个用户token获取用户的数据了。

        //校验token的逻辑，


        //允许授权才授权，不允许直接返回，为什么要记录不允许次数呢？现在不需要，如果以后有乱申请授权的可以记录
        //也可以每个都记录 ，以后加这个功能吧，记录每次授权是否成功等等

        //得到对方的对方的key


        //要知道授权给了谁，
        //还有他授权的用户列表

        //授权历史

        //授权用户列表

        // 商户id，用户列表，权限全部，三方信息

        // 商户id，被授权商户id，授权用户，时间，授权权限，全部


        //保存

    }

    @PostMapping("authUserPhoneNum")
    public ResultRO<ThreeAuthUserPhoneNumResultVO> authUserPhoneNum(SocialUserDO user, @RequestBody @Valid @NotNull ThreeAuthUserInfoQueryVO authVO) {
        //等于校验了，devId，
        //目前只有清池可以授权
        Integer devId = DevAccountUtils.getDevId();
        if (!devId.equals(1)) {
            return new ResultRO<>("不允许授权");
        }

        String threeSecretKey = authVO.getThreeSecretKey();

        //还能知道密钥是否被盗用
        //校验密钥是否正确
        Optional<DevAccountDO> devAccountDOOptional = devAccountRepository.findFirstBySecretKey(threeSecretKey);

        if (!devAccountDOOptional.isPresent()) {
            return new ResultRO<>("不存在的开发者商户");
        }

        DevAccountDO threeDevDO = devAccountDOOptional.get();

        //只是记录一个授权记录
        ThreeUserDO threeUserDO = new ThreeUserDO(threeDevDO.getId(), authVO.getThreeUserId(), user.getUserId(), authVO.getProviderAppId(), authVO.getProviderType(), AuthType.phone);

        threeUserDO = threeUserRepository.save(threeUserDO);
        //token有效期三个月
        //生成userToken
        //生成返回对象
        ThreeAuthUserPhoneNumResultVO threeAuthUserInfoResultVO = new ThreeAuthUserPhoneNumResultVO();
        threeAuthUserInfoResultVO.setPhoneNum(user.getPhoneNum());
        return new ResultRO<>(threeAuthUserInfoResultVO);
        //然后三方应用就能拿着这个用户token获取用户的数据了。

        //校验token的逻辑，


        //允许授权才授权，不允许直接返回，为什么要记录不允许次数呢？现在不需要，如果以后有乱申请授权的可以记录
        //也可以每个都记录 ，以后加这个功能吧，记录每次授权是否成功等等

        //得到对方的对方的key


        //要知道授权给了谁，
        //还有他授权的用户列表

        //授权历史

        //授权用户列表

        // 商户id，用户列表，权限全部，三方信息

        // 商户id，被授权商户id，授权用户，时间，授权权限，全部


        //保存

    }
}
